﻿using System;
using System.Windows.Forms;

using Microsoft.ServiceBus.Messaging;

using static System.String;
// ReSharper disable LocalizableElement

namespace Eldert.IoT.Windows.Administration
{
    /// <summary>
    /// Form used to work with administration side of Azure ServiceBus demo.
    /// </summary>
    public partial class AdministrationForm : Form
    {
        private readonly QueueClient _queue = QueueClient.CreateFromConnectionString(Settings.Read("ErrorsQueueConnectionString"), Settings.Read("ErrorsQueue"));
        private readonly TopicClient _topic = TopicClient.CreateFromConnectionString(Settings.Read("EngineAdministrationTopicConnectionString"), Settings.Read("EngineAdministrationTopic"));
        private static EventProcessorHost _eventProcessorHost;

        /// <summary>
        /// Constructor.
        /// </summary>
        public AdministrationForm()
        {
            InitializeComponent();
            LoadShips();
            LoadMaximumTemperature();
            InitializeProcessingHost();

            #region Action on receiving message in queue

            _queue.OnMessage(message =>
            {
                if (textBoxErrors.InvokeRequired)
                {
                    textBoxErrors.Invoke((MethodInvoker)delegate { textBoxErrors.AppendText(Format($"{message.Properties["exceptionmessage"]}{Environment.NewLine}")); });
                }
                else
                {
                    textBoxErrors.AppendText(Format($"{message.Properties["exceptionmessage"]}{Environment.NewLine}"));
                }
            });

            #endregion

            #region Action on closing the form

            Closing += delegate
            {
                Visible = false;
                _eventProcessorHost.UnregisterEventProcessorAsync().Wait(5000); };

            #endregion
        }

        private void InitializeProcessingHost()
        {
            // Make sure output from console is written to the textbox
            Console.SetOut(new ConsoleRedirect(textBoxEventHubsData));

            // Create connection string to storage which will hold info on which client is handling which partition 
            var storageConnectionString = $"DefaultEndpointsProtocol=https;AccountName={Settings.Read("StorageAccount")};AccountKey={Settings.Read("StorageAccountKey")}";

            // Create a unique identifier, which will be used to determine which partitions this processor is handling
            //var eventProcessorHostName = Environment.MachineName;
            var eventProcessorHostName = Guid.NewGuid().ToString();

            // Create the processor
            _eventProcessorHost = new EventProcessorHost(eventProcessorHostName, Settings.Read("FieldHubEventHub"), Settings.Read("FieldHubEventHubConsumerGroup")
                /* EventHubConsumerGroup.DefaultGroupName */, Settings.Read("FieldHubEventHubConnectionString"), storageConnectionString);

            // Register the processor, at this point one or more partitions will be registered with the client, and it will start processing
            _eventProcessorHost.RegisterEventProcessorAsync<SimpleEventProcessor>();
        }

        private void SendMaximumTemperature(object sender, EventArgs e)
        {
            var message = new BrokeredMessage();
            message.Properties.Add("ship", comboBoxShips.Text);
            message.Properties.Add("maximumtemperature", numericUpDownMaximumTemperature.Text);
            _topic.Send(message);
            MessageBox.Show("Temperature sent", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

    #region Controls

        /// <summary>
        /// Check if the send button should be enabled.
        /// </summary>
        private void CheckEnableSendButton(object sender, EventArgs e)
        {
            if (!IsNullOrWhiteSpace(comboBoxShips.Text))
            {
                buttonSend.Enabled = true;
            }
        }

        /// <summary>
        /// Load the ships from the settings file.
        /// </summary>
        private void LoadShips()
        {
            comboBoxShips.Items.AddRange(Settings.Read("Ships").Split(';'));
        }

        /// <summary>
        /// Load the maximum temperature from the settings file.
        /// </summary>
        private void LoadMaximumTemperature()
        {
            numericUpDownMaximumTemperature.Value = Convert.ToInt32(Settings.Read("MaximumTemperature"));
        }

        #endregion
    }
}
